﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;
using System.Collections.ObjectModel;

using ShoppingList.Model;
using ShoppingListEntities;
using Coding4Fun.Phone.Controls;
using System.Threading;
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Threading;
using System;
using System.Linq;
using System.Windows;

namespace ShoppingList.ViewModel
{

    public class ShoppingViewModel : ViewModelBase
    {
        private ShoppingListEntities.ShoppingList currentShoppingList;
        private static Dictionary<string, List<Product>> DictionaryProducts;
        private ShoppingListDataContext dataContext;
        public ShoppingViewModel()
        {

            dataContext = new ShoppingListDataContext(Helpers.DataBaseHelpers.Cnn);
            currentShoppingList = Helpers.ShopListHelpers.getShoppingList();

            // InitItems();
            SetupCommands();
            canShowProducts = true;

            var query = dataContext.ShoppingLists.Where(x => x.ShoppingListId == currentShoppingList.ShoppingListId)
                .Select(x => x.ShoppingListProducts).SingleOrDefault();


            MyListOfShopping = new ObservableCollection<ShoppingListProduct>();
           
            foreach (var item in query)
            {
                MyListOfShopping.Add(item);
            }

            Messenger.Default.Register<string>(this, "PRODUCTITEMS_TOKEN", (param) =>
            {
                if (param == "LoadItems")
                {
                    DispatcherTimer tmr = new DispatcherTimer();
                    tmr.Interval = TimeSpan.FromSeconds(1);
                    tmr.Tick += (s, e) =>
                    {
                        InitItems();
                        tmr.Stop();
                    };
                    tmr.Start();
                }

            });

            Messenger.Default.Register<Helpers.ShopListHelpers.ProductMenuCommands>(this, "SHOPPINGLIST_TOKEN", (param) =>
            {


                ProductJumpListItem product = Products.Where(x => x.ProductId == param.ProductId).FirstOrDefault();
               

                ProductItem = product;
                ShowNewProductCommand.Execute(null);
                
                Messenger.Default.Send("newitem", "SHOPPINGLIST_TOKEN");


            });

            CalculateTotalCost();  
        }



        #region Properties

        private double _Total;
        public double Total
        {
            get { return _Total; }
            set
            {
                _Total = value;
                RaisePropertyChanged("Total");
            }
        }

        private ShoppingListEntities.ShoppingListProduct _MyShopItem;
        public ShoppingListEntities.ShoppingListProduct MyShopItem
        {
            get { return _MyShopItem; }
            set
            {
                _MyShopItem = value;
                RaisePropertyChanged("MyShopItem");
            }
        }
        private ObservableCollection<ShoppingListProduct> _MyListofShopping;
        public ObservableCollection<ShoppingListProduct> MyListOfShopping
        {
            get
            {
                return _MyListofShopping;
            }
            set
            {
                _MyListofShopping = value;
                RaisePropertyChanged("MyListOfShopping");
            }
        }

        private ObservableCollection<ProductElement> _ProductElements;
        public ObservableCollection<ProductElement> ProductElements
        {
            get { return _ProductElements; }
            set
            {
                _ProductElements = value;

                RaisePropertyChanged("ProductElements");
            }
        }

        private ProductElement _CurrentProductElement;
        public ProductElement CurrentProductElement
        {
            get { return _CurrentProductElement; }
            set
            {
                _CurrentProductElement = value;
                RaisePropertyChanged("CurrentProductElement");
            }
        }

        private ProductJumpListItem _ProductItem;
        public ProductJumpListItem ProductItem
        {
            get { return _ProductItem; }
            set
            {
                _ProductItem = value;
                RaisePropertyChanged("ProductItem");
            }
        }

        private ObservableCollection<ProductJumpListItem> _Products;
        public ObservableCollection<ProductJumpListItem> Products
        {
            get { return _Products; }
            set
            {
                _Products = value;
                RaisePropertyChanged("Products");
            }
        }

        private bool _canShowProducts;
        public bool canShowProducts
        {
            get { return _canShowProducts; }
            set
            {
                _canShowProducts = value;
                RaisePropertyChanged("canShowProducts");
            }
        }


        private double _AmountElement;
        public double AmountElement
        {
            get { return _AmountElement; }
            set
            {
                _AmountElement = value;
                RaisePropertyChanged("AmountElement");
            }
        }

        private double _CostElement;
        public double CostElement
        {
            get { return _CostElement; }
            set
            {
                _CostElement = value;
                RaisePropertyChanged("CostElement");
            }
        }
        #endregion

        #region Commands

        public RelayCommand ShowAviableProducts { get; set; }
        public RelayCommand SetupAviableProductsCommand { get; set; }
        public RelayCommand ShowNewProductCommand { get; set; }
        public RelayCommand NewElementCommand { get; set; }
        public RelayCommand<ShoppingListProduct> gotoProductCommand { get; set; }
        public RelayCommand AddProductCommand { get; set; }
        public RelayCommand<object> DeleteMyListProductCommand { get; set; }
        public RelayCommand<object> DeleteElementProductCommand { get; set; }
       


        private void SetupCommands()
        {

            NewElementCommand = new RelayCommand(() => 
            {

                CurrentProductElement = new ProductElement();
            });
            DeleteElementProductCommand = new RelayCommand<object>((obj) =>
            {
                MessageBoxResult i = MessageBox.Show("Realmente deseas eliminar este elemento?","ADVERTENCIA",MessageBoxButton.OKCancel);

                if (i == MessageBoxResult.OK)
                {
                    ProductElement elementitem = obj as ProductElement;
                    dataContext.ProductElements.DeleteOnSubmit(elementitem);
                    dataContext.SubmitChanges();
                    ProductElements.Remove(elementitem);
                    CalculateCostsListElements();
                    CalculateTotalCost();
                }
               
            });

            DeleteMyListProductCommand = new RelayCommand<object>((obj) => 
            {
                ShoppingListProduct prod = obj as ShoppingListProduct;
                MessageBoxResult i= MessageBox.Show
                    ("Realmente quieres eliminar este Producto? Se eliminarán todos los elementos agregados a este.","ADVERTENCIA", MessageBoxButton.OKCancel);

                if (i == MessageBoxResult.OK)
                {
                    var collectionelements = dataContext.ProductElements
                        .Where(x => x.ProductId == prod.ProductId && x.ShoppingListId == prod.ShoppingListId);

                    dataContext.ProductElements.DeleteAllOnSubmit(collectionelements);

                    dataContext.ShoppingListProducts.DeleteOnSubmit(prod);
                    dataContext.SubmitChanges();
                    MyListOfShopping.Remove(prod);
                    CalculateTotalCost();
                }
            
            });

            gotoProductCommand = new RelayCommand<ShoppingListProduct>((obj) =>
            {
                if (MyShopItem != null)
                {
                    this.ProductItem = new ProductJumpListItem();
                    this.ProductItem.CurrentProduct = obj.Product;
                    this.ProductElements = new ObservableCollection<ProductElement>();
                    this.CurrentProductElement = new ProductElement();
                    var collection = dataContext.ProductElements.
                       Where(x => x.ShoppingListId == currentShoppingList.ShoppingListId && x.ProductId == ProductItem.CurrentProduct.ProductId);
                    foreach (ProductElement item in collection)
                    {
                        ProductElements.Add(item);
                    }
                    CalculateCostsListElements();
                   
                    Messenger.Default.Send("newitem", "SHOPPINGLIST_TOKEN");
                }
                CalculateTotalCost();
                
            });
            AddProductCommand = new RelayCommand(() =>
            {
                if (ProductItem != null && CurrentProductElement != null)
                {
                    if(!Helpers.StringHelpers.OnlyNumbersWithOneDecimal(CurrentProductElement.Cost)){
                        MessageBox.Show("El campo Costo debe tener numeros validos ejemplo: 234 ó 234.1");
                        return;
                    }
                    if (!Helpers.StringHelpers.OnlyNumbersWithOutDecimals(CurrentProductElement.Amount))
                    {
                        MessageBox.Show("El campo Cantidad debe tener numeros enteros validos ejemplo: 234");
                        return;
                    }

                    if (CurrentProductElement.Amount <= 0 || CurrentProductElement.Cost <= 0)
                    {
                        MessageBox.Show("La cantidad o el costo deben ser mayor a cero.");
                        return;
                    }

                    // Search the product on the current list of the user
                    var query = dataContext.ShoppingListProducts
                        .Where(x => x.ShoppingListId == currentShoppingList.ShoppingListId
                        && x.ProductId== ProductItem.CurrentProduct.ProductId
                        )
                      .SingleOrDefault();

                    // if the product no exist
                    //I will add the product in the current list of shopping :)
                    if (query == null)
                    {
                        ShoppingListProduct shop = new ShoppingListProduct();
                       
                        shop.ShoppingListId = currentShoppingList.ShoppingListId;
                        shop.ProductId = ProductItem.CurrentProduct.ProductId;

                        var pro = dataContext.ShoppingLists.Where(x => x.ShoppingListId == currentShoppingList.ShoppingListId)
                            .SingleOrDefault();

                        List<ShoppingListProduct> mypro = pro.ShoppingListProducts.ToList();

                        dataContext.ShoppingListProducts.InsertOnSubmit(shop);
                        dataContext.SubmitChanges();
                        MyListOfShopping.Add(shop);
                           

                    }

                    // Add the element of the product 
                    CurrentProductElement.ProductId = ProductItem.CurrentProduct.ProductId;
                    CurrentProductElement.ShoppingListId = currentShoppingList.ShoppingListId;
                    dataContext.ProductElements.InsertOnSubmit(CurrentProductElement);
                     dataContext.SubmitChanges();
                    ProductElements.Add(CurrentProductElement);
                }

                CalculateCostsListElements();
                CalculateTotalCost();
            });

            ShowNewProductCommand = new RelayCommand(() =>
            {
                this.ProductElements = new ObservableCollection<ProductElement>();
                this.CurrentProductElement = new ProductElement();
                var collection = dataContext.ProductElements.
                    Where(x => x.ShoppingListId == currentShoppingList.ShoppingListId && x.ProductId== ProductItem.CurrentProduct.ProductId );

                try
                {
                    foreach (ProductElement item in collection)
                    {
                        ProductElements.Add(item);
                    }
                }
                catch( NullReferenceException ex)
                {

                }
                    
                
                Messenger.Default.Send("newitem", "SHOPPINGLIST_TOKEN");



            });
            ShowAviableProducts = new RelayCommand(() =>
            {
                Helpers.DispatchService.Dispatch(() =>
                {
                    canShowProducts = false;
                    //  InitItems();
                });

            });

            SetupAviableProductsCommand = new RelayCommand(() =>
            {
                Helpers.DispatchService.Dispatch(() =>
               {


                   InitItems();
               });

            });
        }
        #endregion


        #region Methods

        public void CalculateTotalCost()
        {

                     
            var accounts = dataContext.ShoppingLists;

            List<ShoppingListEntities.ShoppingList> list = accounts.ToList();
           
            var query = list.Where(x => x.ShoppingListId== currentShoppingList.ShoppingListId);
            Total = 0.00;

            foreach (var item in query)
            {
                
                double count = 0.00;
              


                var shoppingproducts = dataContext.ShoppingListProducts
                    .Where(x => x.ShoppingListId == item.ShoppingListId);

                foreach (var shop in shoppingproducts)
                {


                    var elements = dataContext.ProductElements.Where(x => x.ProductId == shop.ProductId && x.ShoppingListId == shop.ShoppingListId);


                    foreach (var element in elements)
                    {
                        count += element.Cost;
                    }

                }

                Total = count;
            }


        }
     

        private void CalculateCostsListElements()
        {
            AmountElement = 0; CostElement = 0;
            foreach (var item in ProductElements)
            {
                AmountElement += item.Amount;
                CostElement += item.Cost;
            }

        }
        public void InitItems()
        {
            bool isHeader = false;
            Products = new ObservableCollection<ProductJumpListItem>();
            DictionaryProducts = Helpers.ShopListHelpers.getAviableJumpListProducts();
            int count = 0;
            foreach (var item in DictionaryProducts)
            {
                count = 1;


                foreach (var subitem in item.Value)
                {
                    if (count == 1) { isHeader = true; }
                    if (isHeader) { Products.Add(new ProductJumpListItem(count, item.Key) { IsEnabled = true, IsHeader = true }); isHeader = false; }
                    count++;
                    ProductJumpListItem jump = new ProductJumpListItem(count, item.Key);
                    jump.CurrentProduct = subitem;
                    jump.ProductId = subitem.ProductId.ToString();
                    Products.Add(jump);

                }
                isHeader = true;

               
            }

           


        #endregion
        }
    }
}